import 'dart:async';
import 'dart:isolate';

/// 任务管理器，一个任务管理器名对应一个单例，保证任务顺序执行
class TaskHelperIsolute<T> {
  Future<void> _executionChain = Future.value(null);
  Completer<void>? _allTasksCompleter;
  int _pendingCount = 0;
  final String helperName;

  TaskHelperIsolute._internal(this.helperName);

  static final Map<String, TaskHelperIsolute> _instances = {};

  factory TaskHelperIsolute(String helperName, void Function(T) isolateFun, T params) =>
      _instances.putIfAbsent(helperName, () {
        final instance = TaskHelperIsolute._internal(helperName) as TaskHelperIsolute<T>;
        instance._initIsolate(isolateFun, params);
        return instance;
      }) as TaskHelperIsolute<T>;

  @override
  int get hashCode => helperName.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is TaskHelperIsolute && helperName == other.helperName;

  void _initIsolate(void Function(T) isolateFun, T params) {
    //创建一个消息接收器
    ReceivePort receivePort = ReceivePort();
    //创建isolate
    Isolate.spawn(isolateFun, params);
    //接收其他isolate发过来的消息
    receivePort.listen((massage) {
      print(massage); //我来自 isolateNew
    });
  }

  void _isolateNew(_Params params) {
      params.sendPort.send('我是来自 isolateNew');
  }

  /// 添加一个任务，并返回一个Future，当任务执行完成时，Future会返回结果，如果任务执行失败，Future会抛出异常
  Future<T> addTask<T>(Function task) {
    if (_pendingCount == 0) {
      _allTasksCompleter = Completer();
    }
    _pendingCount++;

    final taskCompleter = Completer<T>();

    _executionChain = _executionChain.then((_) async {
      try {
        final result = await task();
        taskCompleter.complete(result);
      } catch (e, s) {
        taskCompleter.completeError(e, s);
      } finally {
        if (--_pendingCount == 0) {
          _allTasksCompleter?.complete();
        }
      }
    });

    return taskCompleter.future;
  }

  /// 添加一个任务，当任务队列为空时，才执行该任务，否则返回null
  Future<T?> addTaskWhileIdle<T>(Function task) {
    if (_pendingCount != 0) {
      return Future.value(null);
    }
    return addTask(task);
  }

  /// 等待所有任务执行完成
  Future<void> waitAllTaskDone() async {
    if (_pendingCount == 0) return;
    await _allTasksCompleter?.future;
  }
}

class _Params {
  final SendPort sendPort;
  _Params(
    this.sendPort,
  );
}